package com.nc.delivery_project.client;

import com.google.gwt.activity.shared.ActivityManager;
import com.google.gwt.activity.shared.ActivityMapper;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.shared.SimpleEventBus;
import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.place.shared.PlaceHistoryHandler;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.event.shared.EventBus;
import com.nc.delivery_project.client.add_department.AddDepartmentPlace;
import com.nc.delivery_project.client.add_schedule.AddSchedulePlace;
import com.nc.delivery_project.client.add_user.AddUserPlace;
import com.nc.delivery_project.client.department_details.DepartmentDetailsPlace;
import com.nc.delivery_project.client.departments.DepartmentsPlace;
import com.nc.delivery_project.client.cargo_details.CargoDetailsPlace;
import com.nc.delivery_project.client.order_details.OrderDetailsPlace;
import com.nc.delivery_project.client.orders.OrdersPlace;
import com.nc.delivery_project.client.request.AppRequestFactory;
import com.nc.delivery_project.client.schedules.SchedulesPlace;
import com.nc.delivery_project.client.user_details.UserDetailsPlace;
import com.nc.delivery_project.client.schedule_details.ScheduleDetailsPlace;
import com.nc.delivery_project.client.statistics.StatisticsPlace;
import com.nc.delivery_project.client.statistics.StatisticsPlace.Tokenizer;
import com.nc.delivery_project.client.users.UsersPlace;

public class ClientFactoryImpl implements ClientFactory {

    /**
     * shell for the app
     */
    private MainLayout mainLayout = new MainLayout();

    /**
     * default start point in application
     */
    private Place defaultPlace = new UsersPlace("");

    /**
     * for app's global events
     */
    private static final EventBus eventBus = new SimpleEventBus();

    /**
     * for datastore persistence calls
     */
    private final AppRequestFactory requestFactory = GWT.create(AppRequestFactory.class);

    /**
     * place's directory
     */
    private final ActivityMapper activityMapper = new AppActivityMapper(this);

    /**
     * place's director
     */
    private final ActivityManager activityManager = new ActivityManager(activityMapper, eventBus);

    /**
     * URL tokenizer directory
     */
    private final AppPlaceHistoryMapper historyMapper = GWT.create(AppPlaceHistoryMapper.class);

    /**
     * URL tokenizer's director
     */
    private final PlaceHistoryHandler placeHistoryHandler;

    /**
     * app place's director
     */
    private final PlaceController placeController = new PlaceController(eventBus);

    public ClientFactoryImpl() {

        RootPanel.get().add(mainLayout);

        activityManager.setDisplay(mainLayout.getContentPanel());

        requestFactory.initialize(eventBus);

        // tell the historyMapper there are tokenizers (below) to use in here.
        historyMapper.setFactory(this);

        placeHistoryHandler = new PlaceHistoryHandler(historyMapper);
        placeHistoryHandler.register(placeController, eventBus, defaultPlace);

        mainLayout.setClientFactory(this);

        // Goes to the place represented on URL else default place
        placeHistoryHandler.handleCurrentHistory();
    }

    @Override
    public EventBus getEventBus() {
        return eventBus;
    }

    @Override
    public AppRequestFactory getRequestFactory() {
        return requestFactory;
    }

    @Override
    public PlaceController getPlaceController() {
        return placeController;
    }

    @Override
    public ActivityManager getActivityManager() {
        return activityManager;
    }

    /**
     * Used by the HistoryMapper { @link ApplicationPlaceHistoryMapper }
     * Picked up by the historyMapper when needed.
     * this way, I can send in objects like the requestFactory into them and use it
     * otherwise, the HistoryMapper runs decoupled with this here we can push objects into it.
     */
    @Override
    public UsersPlace.Tokenizer getUsersTokenizer() {
        return new UsersPlace.Tokenizer(requestFactory);
    }

    @Override
    public SchedulesPlace.Tokenizer getSchedulesTokenizer() {  return new SchedulesPlace.Tokenizer(requestFactory);
    }
    @Override
    public UserDetailsPlace.Tokenizer getUserDetailsTokenizer() {
        return new UserDetailsPlace.Tokenizer(requestFactory);
    }

    @Override
    public ScheduleDetailsPlace.Tokenizer getScheduleDetailsTokenizer() {
        return new ScheduleDetailsPlace.Tokenizer(requestFactory);
    }

    @Override
    public OrdersPlace.Tokenizer getOrdersTokenizer() {
        return new OrdersPlace.Tokenizer(requestFactory);
    }

    @Override
    public OrderDetailsPlace.Tokenizer getOrderDetailsTokenizer() {
        return new OrderDetailsPlace.Tokenizer(requestFactory);
    }

    @Override
    public CargoDetailsPlace.Tokenizer getCargoDetailsTokenizer() {
        return new CargoDetailsPlace.Tokenizer(requestFactory);
    }

    @Override
    public AddUserPlace.Tokenizer getAddUserTokenizer() {
        return new AddUserPlace.Tokenizer(requestFactory);
    }


	@Override
	public DepartmentsPlace.Tokenizer getDepartmentsTokenizer() {
		return new DepartmentsPlace.Tokenizer(requestFactory);
	}



    @Override
    public AddSchedulePlace.Tokenizer getAddScheduleTokenizer() {
        return new AddSchedulePlace.Tokenizer(requestFactory);
    }

	@Override
	public AddDepartmentPlace.Tokenizer getAddDepartmentTokenizer() {
		return new AddDepartmentPlace.Tokenizer(requestFactory);
	}

	@Override
	public DepartmentDetailsPlace.Tokenizer getDepartmentDetailsTokenizer() {
		return  new DepartmentDetailsPlace.Tokenizer(requestFactory);
	}

	@Override
	public Tokenizer getStatisticsTokenizer() {
		return new StatisticsPlace.Tokenizer(requestFactory);
	}
	
	

}